package edu.krazy.server;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import edu.krazy.common.GameState;
import edu.krazy.common.MessageType;

public class KrazyGame implements IOnClientMessage {
	
	private String mName;
	private ArrayList<KrazyClient> mClients;
	private ArrayList<KrazyClient> mNotReady;
	private ArrayList<KrazyClient> mReady;
	private IOnClientMessage mParent;
	private int mState;
	private String mCreator;
	
	public String getName(){
		return mName;
	}
	
	public KrazyGame(String name, IOnClientMessage parent){
		mName = name;
		mClients = new ArrayList<KrazyClient>();
		mState = GameState.LOBBY;
		mParent = parent;
	}
	
	public void addClient(KrazyClient toAdd){
		synchronized (mClients) {
			if(!mClients.contains(toAdd)){
				if(mClients.size() == 0){
					mCreator = toAdd.getUsername();
				}
				mClients.add(toAdd);
				toAdd.setListener(this);
				String list =  getUsernameList();
				mClients.notify();
				toAdd.writeToClient(MessageType.JOINED_GAME, list);
				broadcastString(toAdd, MessageType.PLAYER_LIST, list);
			}
		}		
	}
	
	private String getUsernameList(){
		int len = mClients.size();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < len; i++) {
			if(i>0){
				sb.append(",");
			}
			sb.append(mClients.get(i).getUsername());
			
		}
		return sb.toString();
	}

	@Override
	public void broadcastObject(KrazyClient from, int msgType, Object object) {
		int len = mClients.size();
		for (int i = 0; i < len; i++) {
			KrazyClient clnt;
			if(from != (clnt = mClients.get(i))){
				clnt.writeToClient(msgType, from.getUsername(), object);
			}
		}
	}
	
	@Override
	public void broadcastString(KrazyClient from, int msgType, String object) {
		int len = mClients.size();
		for (int i = 0; i < len; i++) {
			KrazyClient clnt;
			if(from != (clnt = mClients.get(i))){
				clnt.writeToClient(msgType, object);
			}
		}		
	}

	@Override
	public void changeGameState(KrazyClient admin, int newState) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void createLobby(KrazyClient creator, String gameName) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void startGame() {
		if(mState == GameState.READY_GAME){
			mState = GameState.IN_PROGRESS;
			
			mClients = mReady;
			int len = mNotReady.size();
			for (int i = 0; i < len; i++) {
				mNotReady.get(i).writeToClient(MessageType.NEVER_READY);
				mNotReady.get(i).setListener(null);
			}
			
			mNotReady = null;
						
			broadcastString(null, MessageType.START_GAME, getUsernameList());
		}
		
	}

	@Override
	public void joinGame(KrazyClient from, String gameName) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void broadcastMessageType(KrazyClient from, int msgType) {
		int len = mClients.size();
		for (int i = 0; i < len; i++) {
			KrazyClient clnt;
			if(from != (clnt = mClients.get(i))){
				clnt.writeToClient(msgType);
			}
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public void readyGame() {
		mState = GameState.READY_GAME;
		mNotReady = (ArrayList<KrazyClient>) mClients.clone();
		mReady = new ArrayList<KrazyClient>();
		new Timer().schedule(new TimerTask() {
			
			@Override
			public void run() {
				startGame();
				
			}
		}, 15000);
	}

	@Override
	public void readyPlayer(KrazyClient client) {
		System.out.println("readyPlayer ");
		if(mState == GameState.READY_GAME){
			mNotReady.remove(client);
			mReady.add(client);
			System.out.println("not ready size: "+mNotReady.size());
			if(mNotReady.size() == 0){
				startGame();
			}
		}
	}

	@Override
	public void leaveGame(KrazyClient client) {
		synchronized (mClients) {
			mClients.remove(client);
		}		
		//if is creator remove all
		if(client.getUsername().equals(mCreator)){
			while(mClients.size()>0) {
				KrazyClient other = mClients.remove(0);
				mParent.addClient(other);
			}
			mParent.destroyGame(this);
		}else{
			broadcastString(null, MessageType.PLAYER_LIST, getUsernameList());
			mParent.addClient(client);
		}
	}

	@Override
	public void clientDisconnected(KrazyClient client) {
		synchronized (mClients) {
			mClients.remove(client);
		}
		//if is creator remove all
		if(client.getUsername().equals(mCreator)){
			while(mClients.size()>0) {
				KrazyClient other = mClients.remove(0);
				mParent.addClient(other);
			}
			mParent.destroyGame(this);
		}else if(mState != GameState.IN_PROGRESS && mState != GameState.READY_GAME){
			broadcastString(null, MessageType.PLAYER_LIST, getUsernameList());
		}
	}

	@Override
	public void destroyGame(KrazyGame game) {
		// TODO Auto-generated method stub
		
	}
}
